package com.ksyun.campus.dataserver.services;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ksyun.campus.dataserver.domain.FileInfo;
import com.ksyun.campus.dataserver.domain.FileType;
import com.ksyun.campus.dataserver.mapper.FileMapper;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;

@Component
public class RegistService implements ApplicationRunner {

    @Value("${server.ip}")
    private String ip;

    @Value("${server.port}")
    private int port;

    @Value("${capacity}")
    private int capacity;

    @Value("${az.azname}")
    private String azname;

    @Value("${az.rack}")
    private String rack;

    @Value("${az.zone}")
    private String zone;

    @Value("${server.connectString}")
    private String connectString;

    private CuratorFramework client;

    @Autowired
    private FileMapper fileMapper;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(500, 5);
        //RetryPolicy retryPolicy = new RetryForever(500);

        client = CuratorFrameworkFactory.builder().connectString(connectString) //虚拟机地址
                .sessionTimeoutMs(60 * 1000)
                .connectionTimeoutMs(60 * 1000)
                .retryPolicy(new ExponentialBackoffRetry(3000, 10))
                //.namespace() //命名空间
                .build();

        System.out.println("开始启动client");
        long startTime = System.currentTimeMillis(); // 记录开始时间
        client.start(); //很耗时间
        System.out.println("启动成功client");
        long endTime = System.currentTimeMillis(); // 记录结束时间
        long duration = (endTime - startTime) / 1000; // 计算耗时（秒）
        System.out.println("启动耗时: " + duration + "秒");

        registToCenter();
    }

    public void registToCenter() throws Exception {
        System.out.println("开始注册节点");
        long startTime = System.currentTimeMillis(); // 记录开始时间

        //向mysql查询useCapacity和fileTotal
        QueryWrapper<FileInfo> wrapper=new QueryWrapper<>();
        String selfDsID="dataServer"+ip+"-"+port;
        wrapper.eq("folder_type", FileType.File.getCode());
        wrapper.and(wrapper1 -> wrapper1
                .eq("copy_location_one", selfDsID)
                .or()
                .eq("copy_location_two", selfDsID)
                .or()
                .eq("copy_location_three", selfDsID)
        );

        List<FileInfo> list = fileMapper.selectList(wrapper); //找出所有保存在此ds的文件
        int fileNum = list.size();
        Long totalSizelong = list.stream()
                .mapToLong(FileInfo::getFileSize)
                .sum();
        int useCapacity=totalSizelong.intValue();

        String data=ip+","+port+","+azname+","+rack+","+zone+","+capacity+","+useCapacity+","+fileNum;
        String path="/server/dataServer/dataServerInstance";
        client.create().creatingParentsIfNeeded()
                .withMode(CreateMode.EPHEMERAL_SEQUENTIAL)
                .forPath(path,data.getBytes());

        System.out.println("成功注册节点");
        long endTime = System.currentTimeMillis(); // 记录结束时间
        long duration = (endTime - startTime) / 1000; // 计算耗时（秒）
        System.out.println("注册耗时: " + duration + "秒");
    }

    //目前所有ds列表ip->port
    public List<Map<String, Integer>> getDslist() {
        return null;
    }

    public void closeZKClient()
    {
        if(client!=null)
        {
            System.out.println("开始关闭client");
            long startTime = System.currentTimeMillis(); // 记录开始时间
            client.close();
            System.out.println("成功关闭client");
            long endTime = System.currentTimeMillis(); // 记录结束时间
            long duration = (endTime - startTime) / 1000; // 计算耗时（秒）
            System.out.println("关闭耗时: " + duration + "秒");
        }
    }

}
